#include "syscall.h"
typedef int bool;

#define true 1
#define false 0
#define NULL 0

#define MAX_CRNum 3 
#define MAX_ClerkNum 3
#define MAX_StockBoyNum 3
#define MAX_CustomerNum 20

#define MinPrices 1
#define PriceFactor 100

/*Environment Varible*/
int CRNum;
int ClerkNum;
int StockBoyNum;
int CustomerNum;
#define AisleNum 5
#define ItemNum 10

/*Tricks*/
/*These Varibles is used to create specific scenario for test cases*/
int ReturnChance;					/*The chance if a customer to be return customer*/
int LostChance;						/*The chance a customer fails to find an item*/
int OriginItemAmount;					/*Origin Amount of each Item*/
int MinBoughtEach;					/*Min number of items a customer can buy*/
int MaxBoughtEach;					/*Max number of items a customer can buy is [MinBoughtEach+MaxBoughtEach-1]*/
int BornLazy;						/*If a clerk will go to rest as soon as he is created?*/
/*int PriceFactor;*/					/*The Factor that affects randomly generated prices*/
/*int MinPrice;*/						/*The Mininum price can be generated*/
bool ManagerTrackLine;					/*Does Manager keep track of Line himself*/
bool CustomerBusyWaiting;
int ProgramRun;
int TotalSales;						/*record the total sales amount.*/

/*Locks*/
int initLock;
int idLock;							/*Lock to pretect id from race condition*/
int OpLock1;							/*StartLine Exclusion*/
int OpLock2;							/*StockBoy Break Exclusion*/
int OpLock3;							/*Clerk Break Exclusion*/
int OpLock4;							/*Leaving Customer Exclusion*/
int OpLock5;							/*For StockRoom Condition Check	*/
int TableLock[MAX_CRNum];				/*Acquire this Lock before handle items on table*/
int CheckQueue;							/*Acquire this lock before check Line Lengths*/
int ScreenLock[MAX_CRNum];				/*Acquire this Lock before interact with cash register machine*/
int StockRoomLock;						/*The Lock on StockRoom*/
int ServiceButtonLock;					/*The Lock to protect service button*/
int ClerkCallLock;						/*The Lock to protect clerk call flag*/
int StockBoyStatusLock;					/*The Lock to protect Stock Boy Status*/
int AisleHelpLock[AisleNum];		/*The Lock to protect AisleHelp related monitor varibles*/
int AisleLock[AisleNum];			/*Acquire this Lock before access any item on an aisle*/
int ServiceStateLock[MAX_StockBoyNum];	/*The Lock to protect help state between a stock boy and a customer*/

/*CVs*/
int StartLine;							/*the start line*/
int ClerkOnBreak;						/*The Condition that clerks on break wait on*/
int StockBoyOnBreak;					/*The Condition that stockboys on break wait on*/
int Queue[MAX_CRNum];					/*Paying Lines*/
int Screen[MAX_CRNum];					/*The cash register machine screen State Condition*/
int Table[MAX_CRNum];					/*The Cashier Table State Condition*/
int LackMoney[MAX_CRNum];				/*If a cash register lacks money to pay return customer, he waits for Manager here*/
int StockRoomCV;						/*The Condition on which Stock Boy wait for room*/
int WaitForRestockCV[ItemNum];		/*Customers waiting for item to be restocked. It is protected by AisleLock*/
int ServiceStateCV[MAX_StockBoyNum];	/*The State Condition when a stock boy is helping a customer*/
int AisleHelpCV[AisleNum];			/*The Condition a customer waits on before a stock boy comes to serve him*/
/*Synchronization Define End*/

/*Shared Varible End*/
int AisleNeedRestock;	/*record if an aisle need to be restocked*/
int ServiceButtonOn;	/*false*/
			/*If somebody pressed service button?*/
int ClerkCall;  	/*false;*/					/*If somebody ask for more clerk?*/
int ClerkCallId;					/*The Clerk who asked manager to wake another clerk*/

int QueueLength;			/*Lengths of paying Lines*/
int ClerkOnWork;			/*If a Clerk is ready for customer?*/
		
int TableArea;				/*Place to put items*/
int CashArea;				/*Place to put money*/

int data;				/*The data is the place to exchange information with cash register*/
int MoneyCollected;			/*The money each cash register earned before manager empty it*/
int TotalMoneyCollected;		/*The money each cash register ever earned*/
int MoneyLacked;			/*The money a cash register lacks to pay a return customer*/

int StockBoyInRoom;			/*Id of StockBoy currently in Stock Room*/

int StockBoyStatus;			/*Each StockBoy's status.If he is in an aisle, status is the aisle number or aisle+AisleNum; Otherwise,  -1*/
int AisleHelpLineLength;		/*The number of customer waiting for help on each aisle*/
int Booklet;				/*The booklet used by Customer and StockBoy to exchange information*/

int CustomerLeaving;			/*Total number of customers that finished shopping and left*/

int DidSomething;                        /*[MAX_StockBoyNum];*/
int Prices;
int ItemAmount;
int ItemRestockPrediction;

/*ID Assignment*/
int nextManagerID;
int nextCustomerID;
int nextClerkID;
int nextStockBoyID;
int nextCashRegisterID;

int GenRandom(int limit)
{
	return Random(limit);
}

int modifyName(char * name, int offset, int num)
{
	int i=0;
	int pos=0;
	int digit;
	if(name == NULL) return -1;
	while(name[i]!='\0' && i<offset+4){
		i++;
	}
	if(name[i]=='\0' && i < offset+4) return -1;
	pos= i-1;
	while(num!=0){
		digit=num%10;
		num = (num-digit)/10;
		name[pos]=(char)(digit+48);
		pos--;
	}
	for(;pos>=offset;pos--)
		name[pos]='0';
	return 1;
}

void initialize()
{
	char* name;
	int numbers[6];
	int i;
		
	nextManagerID = CreateMV("nextManagerID",13,1,0);
	nextCustomerID = CreateMV("nextCustomerID",14,1,0);
	nextClerkID = CreateMV("nextClerkID",11,1,0);
	nextStockBoyID = CreateMV("nextSBID",14,1,0);
	nextCashRegisterID = CreateMV("nextCRID",18,1,0);

	CRNum = GetMV(CreateMV("CRNum",5,1,MAX_CRNum),0);
	ClerkNum = GetMV(CreateMV("ClerkNum",8,1,MAX_ClerkNum),0);
	StockBoyNum = GetMV(CreateMV("StockBoyNum",11,1,MAX_StockBoyNum),0);
	CustomerNum = GetMV(CreateMV("CustomerNum",11,1,MAX_CustomerNum),0);	

	OpLock1 = RemoteCreateLock("OperationLock1",15); 		
	OpLock2 = RemoteCreateLock("OperationLock2",15);
	OpLock3 = RemoteCreateLock("OperationLock3",15);
	OpLock4 = RemoteCreateLock("OperationLock4",15);
	OpLock5 = RemoteCreateLock("OperationLock5",15);
	idLock= RemoteCreateLock("IDLock",7);
	StartLine =  RemoteCreateCondition("StartLine",10);
	ClerkOnBreak =  RemoteCreateCondition("ClerkBreak",11);
	StockBoyOnBreak =  RemoteCreateCondition("StockBoyBreak",14);
	CheckQueue = RemoteCreateLock("CheckQueueLock",15);
	StockRoomLock = RemoteCreateLock("StockRoomLock",14);
	StockRoomCV = RemoteCreateCondition("StockRoomCV",12);
	ServiceButtonLock = RemoteCreateLock("ServiceButtonLock",18);
	StockBoyStatusLock = RemoteCreateLock("StockBoyStatusLock",19);
	ClerkCallLock=RemoteCreateLock("ClerkCallLock",14);

	/*MV initialize*/
	ReturnChance = CreateMV("ReturnChance",12,1,20);	/*The chance if a customer to be return customer*/
	LostChance = CreateMV("LostChance",10,1,25);		/*The chance a customer fails to find an item*/
	OriginItemAmount = CreateMV("OriginItemAmount",16,1,3);	/*Origin Amount of each Item*/
	MinBoughtEach = CreateMV("MinBoughtEach",13,1,1);	/*Min number of items a customer can buy*/
	MaxBoughtEach = CreateMV("MaxBoughtEach",13,1,10);	/*Max number of items a customer can buy is [MinBoughtEach+MaxBoughtEach-1]*/
	/*PriceFactor = CreateMV("PriceFactor",11,1,100);*/		/*The Factor that affects randomly generated prices*/
	/*MinPrice = CreateMV("MinPrice",8,1,0);*/			/*The Mininum price can be generated*/
	ManagerTrackLine = CreateMV("ManagerTrackLine",16,1,true);/*Does Manager keep track of Line himself*/
	
	ProgramRun=CreateMV("ProgramRun",10,1,true);
	TotalSales=CreateMV("TotalSales",10,1,0);
	CustomerBusyWaiting = CreateMV("CustomerBusyWaiting",19,1,false);
	ServiceButtonOn=CreateMV("ServiceButtonOn",15,1,0);
	ClerkCall=CreateMV("ClerkCall",9,1,0);
	ClerkCallId=CreateMV("ClerkCallId",11,1,-1);
       	StockBoyInRoom=CreateMV("StockBoyInRoom",14,1,-1);
       	CustomerLeaving=CreateMV("CustomerLeaving",15,1,0);
	
	/*For CR-related MV*/
	QueueLength=CreateMV("QueueLength",11,CRNum,0);
	ClerkOnWork=CreateMV("ClerkOnWork",11,CRNum,1);
	BornLazy=CreateMV("BornLazy",8,CRNum,0);
	TableArea=CreateMV("TableArea",9,CRNum,-1);	
	CashArea=CreateMV("CashArea",8,CRNum,0);
	data=CreateMV("data",4,CRNum,-1);			/*-1 is used to denote initial state for cash register*/
	MoneyCollected=CreateMV("MoneyCollected",14,CRNum,0);
	TotalMoneyCollected=CreateMV("TotalMoneyCollected",19,CRNum,0);
	MoneyLacked=CreateMV("MoneyLacked",11,CRNum,-1);

	/*For stockboy-related MV*/
	Booklet=CreateMV("Booklet",7,StockBoyNum,-1);	
	StockBoyStatus = CreateMV("StockBoyStatus",14,StockBoyNum,-1);/*StockBoyStatus == -1 means he is out of any aisle*/
	DidSomething=CreateMV("DidSomething",12,StockBoyNum,false);

	/*For aisle-related MV*/
	AisleNeedRestock=CreateMV("AisleNeedRestock",16,AisleNum,0);	/*no aisle need to be restocked at very beginning*/
	AisleHelpLineLength=CreateMV("AisleHelpLineLength",19,AisleNum,0);/*originally no customer is waiting for help in any aisle*/
	/*Initialization of array varibles declared*/

	/*For item-related MV*/
	Prices=CreateMV("Prices",6,ItemNum,0);
	ItemRestockPrediction=CreateMV("ItemRestockPrediction",21,ItemNum,0);/*Item to be restocked is 0	*/
	ItemAmount = CreateMV("ItemAmount",10,ItemNum,3);	/*Origin Amount of each Item*/
	
	for(i=0;i<CRNum;i++)
	{
		/*char* name;*/
		name="Queue0000";
		modifyName(name,5,i);	
		Queue[i] = RemoteCreateCondition(name,9);
		
		name="TableLock0000";
		modifyName(name,9,i);
		TableLock[i]=RemoteCreateLock(name,13);
		
		name="Table0000";
		modifyName(name,5,i);
		Table[i]=RemoteCreateCondition(name,9);
		
		name="ScreenLock0000";
		modifyName(name,10,i);
		ScreenLock[i]=RemoteCreateLock(name,14);
			
		name="Screen0000";
		modifyName(name,6,i);
		Screen[i]=RemoteCreateCondition(name,10);
		
		name="Lack0000";
		modifyName(name,4,i);
		LackMoney[i]=RemoteCreateCondition(name,8);
	}

	for(i=0;i<StockBoyNum;i++)
	{
		name="ServiceStateLock0000";
		modifyName(name,16,i);
		ServiceStateLock[i]=RemoteCreateLock(name,20);
		
		name="ServiceState0000";
		modifyName(name,12,i);
		ServiceStateCV[i]=RemoteCreateCondition(name,16);
	}

	for (i=0;i<AisleNum;i++)
	{
		name="AisleHelpLock0000";
		modifyName(name,13,i);
		AisleHelpLock[i]=RemoteCreateLock(name,17);
		
		name="AisleHelpCV0000";
		modifyName(name,11,i);
		AisleHelpCV[i]=RemoteCreateCondition(name,15);
		
		name="AisleLock0000";
		modifyName(name,9,i);
		AisleLock[i]=RemoteCreateLock(name,13);
	}
	
	for(i=0;i<ItemNum;i++)
	{
		name="WaitForRestockCV0000";
		modifyName(name,16,i);
		WaitForRestockCV[i]=RemoteCreateCondition(name,20);
	}
}


/*---------------------StockBoy Minor--------------------*/
/*StockBoy Behavior*/
/*	the main Logic of a StockBoy*/
/*	by Kuai Yu*/
/*-------------------------------------------------------*/

int GetAisleByItem(int item)
{
	return (item/2);
}
void SBTakeTime(int time)								/*used to let stock boy take some time to do something*/
{
	int i;
	int sum=0;
	for(i=0;i<time * 100; i++ )
		sum += i;
}
void
RetrieveStockItem(int item, int id)						/*Retrieve item form stock room*/
{
	int numbers[6];
	int i;
	int sum;
	/*printf("===StockBoy [%d] want to retrieve item [%d]\n",id,item);*/
	RemoteAcquireLock(OpLock5);				
	while(true)
	{
		if(GetMV(StockBoyInRoom,0)!=-1)							/*If stockroom is currently occupied*/
		{
			numbers[0]=id;
			numbers[1]=GetMV(StockBoyInRoom,0);
			WriteFormat("StockBoy [%d] is waiting for StockBoy [%d] to leave the stock room.\n",69,numbers,2);
			RemoteWaitCondition(StockRoomCV,OpLock5);				/*wait for stock boy in room to leave*/
			continue;									/*Re do check stock room*/
		}
		SetMV(StockBoyInRoom,0,id);							/*If not occupied, register self*/
		RemoteReleaseLock(OpLock5);
		break;
	}
	RemoteAcquireLock(StockRoomLock);							/*Enter stock room*/
	
	numbers[0]=id;
	WriteFormat("StockBoy [%d] is in stock room.\n",33, numbers, 1);

	SBTakeTime(10);									/*It takes time to pick item*/
		
	numbers[1]=item;
	WriteFormat("StockBoy [%d] retrieve one new item [%d] from stock room.\n", 59 , numbers,2 );
	
	WriteFormat("StockBoy [%d] leaves stock room.\n", 34, numbers,1);
	RemoteReleaseLock(StockRoomLock);						/*leave stock room*/
	RemoteAcquireLock(OpLock5);
	/*OpLock5->Acquire();*/
	SetMV(StockBoyInRoom,0,-1);;								/*mark nobody is in stockroom*/
	RemoteSignalCondition(StockRoomCV,OpLock5);						/*tell one stockboy to retry entering stockroom*/
	RemoteReleaseLock(OpLock5);
}

void 
ServeCustomerAndLeaveAisle(int StockBoyId, int MyAisle)	/*Stock boy serve suctomer and leave aisle after that*/
{
	int numbers[6];
	int i;
	/*printf("===StockBoy [%d] want to serve customer in aisle [%d]\n",StockBoyId,MyAisle);*/
	
	if(MyAisle<0)										/*if stockboy is not in any aisle, won't serve customer*/
		return;

	/*char * name = currentThread->getName();*/

	/*printf("=== %s is yielding...\n", name);*/

	SBTakeTime(5);								/*it takes some time to walk to the end of aisle*/
	
	RemoteAcquireLock(AisleHelpLock[MyAisle]);					/*Acquire help lock*/

	while(GetMV(AisleHelpLineLength,MyAisle)>0)				/*while there is still customer waiting for service*/
	{
		int cusId;
		int item;
		int aisle;
		SetMV(DidSomething,StockBoyId,1);				/*I did something when help customer*/

		/*printf("===StockBoy [%d] find [%d] customers waiting in aisle %d\n", StockBoyId, AisleHelpLineLength[MyAisle],MyAisle);*/

		RemoteSignalCondition(AisleHelpCV[MyAisle],AisleHelpLock[MyAisle]);	/*Tell one customer to ask question*/

		SetMV(AisleHelpLineLength,MyAisle,GetMV(AisleHelpLineLength,MyAisle)-1);					/*decrement helpline length*/
		
		RemoteAcquireLock(StockBoyStatusLock);				/*Acquire status lock before release helplock, make sure customer has no chance to run before i am ready*/
	
		RemoteReleaseLock(AisleHelpLock[MyAisle]);

		/*printf("===StockBoy [%d] is waiting to help one customer in aisle %d\n", StockBoyId, MyAisle);*/
	
		SetMV(StockBoyStatus,StockBoyId,MyAisle + AisleNum);/*mark my status as [Aisle +AisleNum], that is the status for ready to serve in aisle;*/

		/*printf("===StockBoy [%d] set his Status: %d\n", StockBoyId, StockBoyStatus[StockBoyId]);*/
		
		RemoteAcquireLock(ServiceStateLock[StockBoyId]);		/*Acquire service state lock, entering service section*/

		RemoteReleaseLock(StockBoyStatusLock);
		
		RemoteWaitCondition(ServiceStateCV[StockBoyId],ServiceStateLock[StockBoyId]);	/* wait for customer to ask question*/
		
		cusId=GetMV(Booklet,StockBoyId);					/*get customer id*/

		RemoteSignalCondition(ServiceStateCV[StockBoyId],ServiceStateLock[StockBoyId]);/* tell customer to go on*/
		
		RemoteWaitCondition(ServiceStateCV[StockBoyId],ServiceStateLock[StockBoyId]);
		
		numbers[0]=StockBoyId;
		numbers[1]=cusId;
		WriteFormat("StockBoy [%d] is approached by Customer [%d] for assistance.\n",62, numbers,2);

		item=GetMV(Booklet,StockBoyId);					/*get customer's question*/

		/*printf("=== %s get a question from customer: where is item%d\n", name, item);*/
		
		aisle = GetAisleByItem(item);				/*find the answer*/

		SetMV(Booklet,StockBoyId,aisle);						/*put answer on booklet*/
		
		numbers[0]=StockBoyId;
		numbers[1]=aisle;
		numbers[2]=cusId;
		numbers[3]=item;
		WriteFormat("StockBoy [%d] gave aisle [%d] to Customer [%d] for item [%d].\n",63,numbers,4);
		
		RemoteSignalCondition(ServiceStateCV[StockBoyId],ServiceStateLock[StockBoyId]);	/*tell customer to read answer*/

		RemoteWaitCondition(ServiceStateCV[StockBoyId],ServiceStateLock[StockBoyId]);		/*wait for customer's thanks*/

		RemoteReleaseLock(ServiceStateLock[StockBoyId]);
		RemoteAcquireLock(AisleHelpLock[MyAisle]);
	}
	RemoteAcquireLock(StockBoyStatusLock);							/*Mark self as out of aisle*/
	/*printf("=== %s leaves aisle%d\n", name, MyAisle);*/
	SetMV(StockBoyStatus,StockBoyId,-1);								

	RemoteReleaseLock(StockBoyStatusLock);
	
	/*printf("===StockBoy [%d] left aisle [%d]\n",StockBoyId,MyAisle);*/

	RemoteReleaseLock(AisleHelpLock[MyAisle]);

}

int
ScanAisle(int id)												/*Stock boy scans aisles to see if items is lacked*/
{
	int i,j,k;
	for (i=0;i<AisleNum;i++)								/*loop all aisles*/
	{
		RemoteAcquireLock(AisleLock[i]);								/*Entering aisle*/
		RemoteAcquireLock(StockBoyStatusLock);
		
		/*printf("=== %s is scanning aisle%d\n", currentThread -> getName(), i );*/
		SetMV(StockBoyStatus,id,i);									/*Update stock boy status. let customer see him*/
		
		RemoteReleaseLock(StockBoyStatusLock);
		
		for(j = 0; j<2; j++)								/*check items on this aisle*/
		{
			int index;
			SBTakeTime(2);									/*it takes time to check item status*/
						
			index = i*2+j;									/*calculate item id*/
			if ((GetMV(ItemAmount,index) + GetMV(ItemRestockPrediction,index))<GetMV(OriginItemAmount,0))/*If Item is lacked, and still have space to restock*/
			{
				SetMV(ItemRestockPrediction,index,GetMV(ItemRestockPrediction,index)+1);					/*Mark item that I will restock one of this item*/
				RemoteReleaseLock(AisleLock[i]);
				ServeCustomerAndLeaveAisle(id,i);				/*Serve customer and leave aisle*/
				return index;									/*Return item id that i am going to restock*/
			}
		}
		RemoteReleaseLock(AisleLock[i]);
		ServeCustomerAndLeaveAisle(id,i);						/*Serve customer before leave aisle*/
	}

	return -1;													/*If no item need to restock, return -1*/
}

/*Assumption: */
/*current thread is holding AisleLock[aisle]*/
bool
isItemFull(int item)											/*Check if item is full*/
{
	return ((GetMV(ItemAmount,item)+GetMV(ItemRestockPrediction,item)) == GetMV(OriginItemAmount,0));
}

bool
isAisleFull(int aisle)											/*Check if aisle is full*/
{
	return ( isItemFull(aisle*2) && isItemFull(aisle*2+1) );
}

bool
PutStockItem(int item, int id)									/*Put retrieved item on its aisle*/
{
	int numbers[6];
	bool more = false;						

	int aisle = GetAisleByItem(item);							/*calculate aisle number*/

	RemoteAcquireLock(StockBoyStatusLock);
	SetMV(StockBoyStatus,id,aisle);									/*Mark self status in that aisle*/
	RemoteReleaseLock(StockBoyStatusLock);

	RemoteAcquireLock(AisleLock[aisle]);								/*Enter aisle*/
	
	SetMV(ItemAmount,item,GetMV(ItemAmount,item)+1);											/*Restock item */
	SetMV(ItemRestockPrediction,item,GetMV(ItemRestockPrediction,item)-1);								/*Delete the mark I left before go get the item*/
	RemoteSignalCondition(WaitForRestockCV[item],AisleLock[aisle]);			/*wake up one customer waiting for item*/
	
	numbers[0]=id;
	WriteFormat("StockBoy [%d] is checking if more items are to be re-stocked.\n",63,numbers,1);
	
	if(isAisleFull(aisle))
	{
		SetMV(AisleNeedRestock,aisle,false);
	}		/*If aisle is full, unset the mark that this aisle need restock*/
	else if(!isItemFull(item))									/*If this item is still lacked, go get another*/
	{
		/*Mark I will tock it again*/
		numbers[1]=item;
		WriteFormat("StockBoy [%d] goes back to stock room for item [%d].\n",54,numbers,2);
		SetMV(ItemRestockPrediction,item,GetMV(ItemRestockPrediction,item)+1);							/*Leave a mark I am already trying to restock one item of this type*/
		more = true;											/*I will get more this item*/
	}
	
	RemoteReleaseLock(AisleLock[aisle]);								/*Leave Aisle*/

	ServeCustomerAndLeaveAisle(id,aisle);						/*Serve customer and leave aisle*/
	
	return more;
}

void
StockBoyRest(int id)											/*Stock boy go to rest*/
{
	WriteFormat("StockBoy [%d] is going on break.\n",34,&id,1);
	RemoteAcquireLock(OpLock2);
	RemoteWaitCondition(StockBoyOnBreak,OpLock2);
	WriteFormat("StockBoy [%d] got call from Manager.\n",38,&id,1);
	RemoteReleaseLock(OpLock2);
}
/*---------------------StockBoy Major--------------------*/
/*StockBoy Behavior*/
/*	the main Logic of a StockBoy*/
/*	by Kuai Yu*/
/*-------------------------------------------------------*/

void
StockBoyBehavior()
{
	int id;
	RemoteAcquireLock(idLock);
	id=GetMV(nextStockBoyID,0);
	SetMV(nextStockBoyID,0,id+1);
	RemoteReleaseLock(idLock);

	while(GetMV(ProgramRun,0))											/*As long as program is running*/
	{
		int item;
	
		WriteFormat("StockBoy [%d] Running...\n",26,&id,1);
	
		SetMV(DidSomething,id,false);
		
		item = ScanAisle(id);								/*Scan aisles for lacked item*/
		
		if(item != -1)											/*if one item is lacked*/
		{
			/*printf("=== %s found item %d is lacked, go to retrieve item\n", name, item);		*/
			int aisle;
			SetMV(DidSomething,id,true);							/*mark self did something in his loop*/
			aisle = GetAisleByItem(item);
		
			RetrieveStockItem(item,id);							/*retrieve one item of this type*/
			/*printf("=== %s is in aisle%d, ready to restock item %d\n", name, aisle, item);*/
			
			while(PutStockItem(item, id))						/*put item on aisle. As long as it is still lacked, get one another and restock*/
			{
				RetrieveStockItem(item,id);
			}
		}

		if(!GetMV(DidSomething,id))									/*If I did nothing in this loop, go to rest*/
		{
			WriteFormat("StockBoy [%d] Sleepy\n",22,&id,1);
			if(!GetMV(ProgramRun,0))										/*If program end, exit*/
				Exit(0);
			/*printf("StockBoy === %s go to have a rest\n", name);*/
			StockBoyRest(id);
		}
	}	
	Exit(0);
}

int main()
{
	initialize();
	StockBoyBehavior();
}
